package com.sls.game.supply.deal;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.google.gson.Gson;
import com.sls.core.common.CommonUtil;
import com.sls.core.http.HttpClient;
import com.sls.core.socket.Head;
import com.sls.core.util.ServerDateAndTime;
import com.sls.core.util.UtilMD5Encryption;
import com.sls.game.common.DeductionRefund;
import com.sls.game.dao.DownstreamUserDAO;
import com.sls.game.dao.GoodsOrderDAO;
import com.sls.game.dao.GoodsSupplyManageDAO;
import com.sls.game.dao.jpay.JpayAreaDAO;
import com.sls.game.dao.jpay.JpayGoodsDAO;
import com.sls.game.parser.jieyitong.ParseConfigOfJieyitong;
import com.sls.game.parser.jieyitong.ParseOrderStatusResMsg;
import com.sls.game.pojo.DeductionRefundInfo;
import com.sls.game.pojo.GoodsOrderInfo;
import com.sls.game.pojo.SLSHttpInterfaceInfo;
import com.sls.game.pojo.jieyitong.JieyitongAreaServerInfo;
import com.sls.game.pojo.jieyitong.JieyitongConfigInfo;
import com.sls.game.pojo.jieyitong.JieyitongGoodsInfo;
import com.sls.game.pojo.jieyitong.OrderStatusResInfo;

/**
 * 捷易通交易处理
 * 
 * @author cx
 * 
 */
public class JpayTradeDeal {

	private static Logger log = Logger.getLogger(JpayTradeDeal.class);

	/**
	 * 处理捷易通交易请求
	 * 
	 * @param info
	 * @param originalGoodsId
	 * @param orderId
	 * @param head
	 * @param orderTime
	 * @param paymentOrderNo
	 * @param jpayAreaDAO
	 * @param downstreamUserDAO
	 * @param jpayGoodsDAO2
	 * @param goodsSupplyManageDAO2
	 * @param goodsOrderDAO2
	 * @return
	 */
	public static String dealTradeResultOfJpay(SLSHttpInterfaceInfo info,
			String originalGoodsId, String orderId, String orderTime,
			String paymentOrderNo, Head head, GoodsOrderDAO goodsOrderDAO,
			GoodsSupplyManageDAO goodsSupplyManageDAO,
			JpayGoodsDAO jpayGoodsDAO, JpayAreaDAO jpayAreaDAO,
			DownstreamUserDAO downstreamUserDAO) {

		// 调用交易方法
		OrderStatusResInfo resInfo = trade(info, originalGoodsId, orderId,
				orderTime, head, goodsOrderDAO, goodsSupplyManageDAO,
				jpayGoodsDAO, jpayAreaDAO);
		// 返回给上层对象
		SLSHttpInterfaceInfo sLSHttpInterfaceInfo = new SLSHttpInterfaceInfo();

		/**
		 * 00请求成功、01提交成功，正在充值、 07库存不足、08用户余额不足、 09用户帐号异常、10号码异常、 11地区维护、12无此面值、
		 * 13系统维护、14校验失败、 15缺少参数、16运营商升级、 18订单号重复、20其他错误（不扣费）、 21非绑定IP、22提交频率过快、
		 * 99未知错误, 需进平台核实（可能扣费）
		 */
		if (resInfo != null) {
			String resultno = resInfo.getResultno();
			String supOrderSuccessTime = ServerDateAndTime.getNowDateTime();
			if ("00".equals(resultno) || "01".equals(resultno)) { // 处理中
				sLSHttpInterfaceInfo.setResMsg("SUCCESS");
				sLSHttpInterfaceInfo.setFailedCode("209");
				sLSHttpInterfaceInfo.setFailedReason("处理中");
				sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
				sLSHttpInterfaceInfo.setStatus("ORDER_UNDERWAY");
				sLSHttpInterfaceInfo.setSupOrderNo(orderId);
			} else if ("02".equals(resultno) || "2".equals(resultno)) {
				sLSHttpInterfaceInfo.setResMsg("SUCCESS");
				sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
				sLSHttpInterfaceInfo.setStatus("ORDER_SUCCESS");
				sLSHttpInterfaceInfo.setSupOrderNo(orderId);
				sLSHttpInterfaceInfo
						.setSupOrderSuccessTime(supOrderSuccessTime);
			} else if ("04".equals(resultno) || "4".equals(resultno)
					|| "99".equals(resultno)) {
				sLSHttpInterfaceInfo.setResMsg("SUCCESS");
				sLSHttpInterfaceInfo.setFailedCode("210");
				sLSHttpInterfaceInfo.setFailedReason("订单存疑");
				sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
				sLSHttpInterfaceInfo.setStatus("ORDER_DUBIOUS");
				sLSHttpInterfaceInfo.setSupOrderNo(orderId);
			} else { // 失败
				sLSHttpInterfaceInfo.setResMsg("FAILED");
				sLSHttpInterfaceInfo.setFailedCode("208");
				sLSHttpInterfaceInfo.setFailedReason("充值失败");
				sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
				sLSHttpInterfaceInfo.setStatus("ORDER_FAILED");
				sLSHttpInterfaceInfo.setSupOrderNo(orderId);

				GoodsOrderInfo goodsOrderInfo1 = new GoodsOrderInfo();
				DeductionRefundInfo dedInfo = null;
				String paymentStatus = "";
				// 退款
				dedInfo = DeductionRefund.invokeDeductRefund(info, orderId,
						"1", orderTime, paymentOrderNo, head, goodsOrderDAO);
				if (dedInfo != null) {
					paymentStatus = dedInfo.getPaymentStatus();
				}
				if ("1".equals(paymentStatus)) { // 成功
					goodsOrderInfo1.setIsPay("3"); // 退款成功
					// 退款成功，通知下游用户
					DeductionRefund.noticeUserRefundMsg(orderId, dedInfo,
							goodsOrderDAO, downstreamUserDAO, null);

				} else if ("2".equals(paymentStatus)) {
					goodsOrderInfo1.setIsPay("2"); // 退款失败
				}
				try {
					// 更新订单
					updateGoodsOrder(orderId, head, goodsOrderInfo1,
							goodsOrderDAO);
				} catch (Exception e) {
					log.error("请求ID：" + head.getRequestId() + "根据退款状态更新订单异常！",
							e);
				}
			}
		} else {
			sLSHttpInterfaceInfo.setResMsg("SUCCESS");
			sLSHttpInterfaceInfo.setFailedCode("210");
			sLSHttpInterfaceInfo.setFailedReason("订单存疑");
			sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
			sLSHttpInterfaceInfo.setStatus("ORDER_DUBIOUS");
			sLSHttpInterfaceInfo.setSupOrderNo(orderId);
		}
		sLSHttpInterfaceInfo.setGameAccount(info.getGameAccount());
		sLSHttpInterfaceInfo.setUnitPrice(info.getUnitPrice());
		sLSHttpInterfaceInfo.setBuyNum(info.getBuyNum());

		String totalPrice = info.getTotalPrice();
		sLSHttpInterfaceInfo.setTotalPrice(totalPrice);
		Gson gson = CommonUtil.gson();
		String resultBody = gson.toJson(sLSHttpInterfaceInfo);

		return resultBody;
	}

	/**
	 * 交易处理
	 * 
	 * @param info
	 * @param originalGoodsId
	 * @param orderId
	 * @param orderTime
	 * @param head
	 * @param jpayGoodsDAO
	 * @param goodsSupplyManageDAO
	 * @param goodsOrderLogDAO
	 * @param goodsOrderDAO
	 * @param jpayAreaDAO
	 * @return
	 */
	private static OrderStatusResInfo trade(SLSHttpInterfaceInfo info,
			String originalGoodsId, String orderId, String orderTime,
			Head head, GoodsOrderDAO goodsOrderDAO,
			GoodsSupplyManageDAO goodsSupplyManageDAO,
			JpayGoodsDAO jpayGoodsDAO, JpayAreaDAO jpayAreaDAO) {

		JieyitongConfigInfo cfg = ParseConfigOfJieyitong.parseConfigInfo();
		String userid = "";
		if (cfg != null) {
			userid = cfg.getUserid();
			if (StringUtils.isNotEmpty(userid)) {
				userid = userid.trim();
			}
		}
		GoodsOrderInfo orderInfo = new GoodsOrderInfo();
		orderInfo.setRegisterAccount(userid);
		updateGoodsOrder(orderId, head, orderInfo, goodsOrderDAO);

		OrderStatusResInfo resInfo = null;
		String url = assembleParameterOfTrade(info, originalGoodsId, orderId,
				orderTime, jpayGoodsDAO, jpayAreaDAO);
		// 发送http请求
		resInfo = sendHttpRequestOfDirectTrade(url, head);

		// 上游订单结果
		String orderResult = "";
		String msg = "";
		String status = "2";
		if (resInfo != null) {
			// 订单结果
			orderResult = resInfo.getResultno();
			msg = map.get(orderResult);

			if ("00".equals(orderResult) || "01".equals(orderResult)
					|| "1".equals(orderResult)) { // 处理中
				status = "2";
			} else if ("02".equals(orderResult) || "2".equals(orderResult)) { // 充值成功
				status = "1";
			} else if ("04".equals(orderResult) || "4".equals(orderResult)
					|| "17".equals(orderResult) || "99".equals(orderResult)) {
				status = "3"; // 存疑
			} else {
				status = "0"; // 失败
			}
		} else {
			status = "3"; // 存疑
		}

		GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
		goodsOrderInfo.setStatus(status);
		goodsOrderInfo.setStatusRemark(msg);
		try {
			// 根据交易返回的结果更新订单表
			updateGoodsOrder(orderId, head, goodsOrderInfo, goodsOrderDAO);
		} catch (Exception e) {
			log.error("请求ID：" + head.getRequestId() + "根据捷易通返回的结果更新订单异常！", e);
		}

		return resInfo;

	}

	/**
	 * 更新订单
	 * 
	 * @param orderId
	 * @param head
	 * @param info
	 * @param goodsOrderDAO
	 */
	private static void updateGoodsOrder(String orderId, Head head,
			GoodsOrderInfo info, GoodsOrderDAO goodsOrderDAO) {
		String status = "";
		String orderResult = "";
		String regAccount = "";
		if (info != null) {
			status = info.getStatus();
			orderResult = info.getResult();
			regAccount = info.getRegisterAccount();
		}
		GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
		goodsOrderInfo.setOrderId(orderId);
		goodsOrderInfo.setStatus(status);
		goodsOrderInfo.setResult(orderResult);
		goodsOrderInfo.setRegisterAccount(regAccount);
		goodsOrderInfo.setSynOrAsy("0"); // 同步通知标识
		if (StringUtils.isNotEmpty(info.getIsPay())) {
			goodsOrderInfo.setIsPay(info.getIsPay());
		}
		// 数据更新
		try {
			goodsOrderDAO.update(goodsOrderInfo);
		} catch (Exception e) {
			log.error(
					"updateGoodsOrder处理[" + head.getRequestId() + "]的请求出现异常！",
					e);
		}
	}

	/**
	 * 向上游发送交易请求
	 * 
	 * @param address
	 * @param paraStr
	 * @param head
	 * @return
	 */
	private static OrderStatusResInfo sendHttpRequestOfDirectTrade(String url,
			Head head) {
		OrderStatusResInfo resInfo = null;
		HttpClient httpClient = new HttpClient();
		try {
			// 供应商返回消息编码方式
			String supplyEncode = "GB2312";
			log.info("请求ID：" + head.getRequestId() + "，发送到捷易通的直充请求url参数为："
					+ url);
			String xmlStr = httpClient.doGet(url, supplyEncode);
			log.info("请求ID：" + head.getRequestId() + "，捷易通直充返回的结果参数为：" + xmlStr);
			// 对返回的xml格式字符串数据进行解析
			resInfo = ParseOrderStatusResMsg.parseRes(xmlStr);
		} catch (Exception e) {
			log.error("请求ID：" + head.getRequestId() + "捷易通直充交易请求异常！", e);
		}
		return resInfo;
	}

	/**
	 * 拼装请求地址
	 * 
	 * @param info
	 * @param originalGoodsId
	 * @param orderId
	 * @param orderTime
	 * @param jpayGoodsDAO
	 * @param jpayAreaDAO
	 * @return
	 */
	private static String assembleParameterOfTrade(SLSHttpInterfaceInfo info,
			String originalGoodsId, String orderId, String orderTime,
			JpayGoodsDAO jpayGoodsDAO, JpayAreaDAO jpayAreaDAO) {
		// 从xml配置文件中读取配置信息
		JieyitongConfigInfo cfg = ParseConfigOfJieyitong.parseConfigInfo();
		String address = "http://agent.jieyitong.net:88/colpost.do";
		String userid = "";
		String md5_key = "";
		String synctype = "0";
		if (cfg != null) {
			address = cfg.getRechargeAddress();
			if (StringUtils.isNotEmpty(address)) {
				address = address.trim();
			}
			userid = cfg.getUserid();
			if (StringUtils.isNotEmpty(userid)) {
				userid = userid.trim();
			}
			md5_key = cfg.getSecretKey();
			if (StringUtils.isNotEmpty(md5_key)) {
				md5_key = md5_key.trim();
			}
			synctype = cfg.getSynctype();
			if (StringUtils.isNotEmpty(synctype)) {
				synctype = synctype.trim();
			}
		}
		String chargetype = originalGoodsId;
		String userAccount = info.getGameAccount();
		String area = info.getGameArea();
		String buyNum = info.getBuyNum();
		int amount = 0;
		JieyitongGoodsInfo jInfo = jpayGoodsDAO.queryByGoodsId(originalGoodsId);
		if (jInfo != null) {
			String parvalue = jInfo.getParValue();
			parvalue = parvalue.substring(0, parvalue.indexOf("."));
			int bNum = 0;
			int parv = 0;
			try {
				bNum = Integer.parseInt(buyNum);
				parv = Integer.parseInt(parvalue);
			} catch (Exception e) {
				log.error("拼装捷易通交易请求参数时出现异常", e);
			}
			amount = bNum * parv;
		}
		String sign = null;
		String data = userid;
		data += "^";
		data += orderId;
		data += "^";
		data += userAccount;
		data += "^";
		data += amount;
		data += "^";
		data += synctype;
		data = data + "^" + md5_key;
		sign = UtilMD5Encryption.createMD5EncryptionOfGBK(data);
		try {
			if (StringUtils.isNotEmpty(userAccount)) {
				userAccount = URLEncoder.encode(userAccount, "GB2312");
			}
		} catch (UnsupportedEncodingException e) {
			log.error("中文编码异常！", e);
		}
		StringBuilder sb = new StringBuilder();
		sb.append(address);
		sb.append("?");
		sb.append("userid=");
		sb.append(userid);
		sb.append("&");
		sb.append("requestid=");
		sb.append(orderId);
		sb.append("&");
		sb.append("mobile=");
		sb.append(userAccount);
		sb.append("&");
		sb.append("amount=");
		sb.append(amount);
		if (StringUtils.isNotEmpty(chargetype)) {
			sb.append("&");
			sb.append("chargetype=");
			sb.append(chargetype.trim());
		}
		if (StringUtils.isNotEmpty(area)) {
			JieyitongAreaServerInfo areaSrvInfo = new JieyitongAreaServerInfo();
			areaSrvInfo.setGoodsId(originalGoodsId);
			areaSrvInfo.setAreaName(area);
			List<JieyitongAreaServerInfo> list = jpayAreaDAO
					.queryByGoodsIdAndAreaName(areaSrvInfo);
			String areaCode = "";
			if (list != null && !list.isEmpty()) {
				JieyitongAreaServerInfo jpayInfo = list.get(0);
				areaCode = jpayInfo.getAreaSrvCode();
			}
			sb.append("&");
			sb.append("area=");
			sb.append(areaCode.trim());
		}
		sb.append("&");
		sb.append("synctype=");
		sb.append(synctype);
		sb.append("&");
		sb.append("vstr=");
		sb.append(sign);
		String parameter = sb.toString();
		return parameter;
	}

	private static Map<String, String> map = new HashMap<String, String>();

	static {
		map.put("00", "请求成功");
		map.put("01", "提交成功,正在充值");
		map.put("1", "提交成功,正在充值");
		map.put("02", "充值成功");
		map.put("2", "充值成功");
		map.put("03", "充值失败");
		map.put("3", "充值失败");
		map.put("04", "部分退款");
		map.put("4", "部分退款");
		map.put("07", "库存不足");
		map.put("7", "库存不足");
		map.put("08", "用户余额不足");
		map.put("8", "用户余额不足");
		map.put("09", "用户帐号异常");
		map.put("9", "用户帐号异常");
		map.put("10", "号码异常");
		map.put("11", "地区维护");
		map.put("12", "无此面值");
		map.put("13", "系统维护");
		map.put("14", "校验失败");
		map.put("15", "缺少参数");
		map.put("16", "运营商升级");
		map.put("17", "无此订单(30分钟内可原订单号重新提交，不可作为失败处理，30分钟外可做失败处理)");
		map.put("18", "订单号重复");
		map.put("19", "订单扣款失败");
		map.put("20", "其他错误（不扣费）");
		map.put("21", "非绑定IP");
		map.put("22", "提交频率过快");
		map.put("23", "查询频率过快");
		map.put("99", "未知错误, 需进平台核实（可能扣费）");
	}
}
